home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9110.ZIP / ACTOR.ASC < prev    next >
Text File  |  1991-09-10  |  13KB  |  439 lines

  1. _ENHANCING THE ACTOR DEVELOPMENT ENVIRONMENT_
  2. by Steve Hatchett
  3.  
  4. [LISTING ONE]
  5.  
  6.  
  7. /* EXTEND.LOD - Actor development extensions load file
  8.  * Copyright(C) 1991 Steve Hatchett.  All rights reserved.
  9.  *    Steve Hatchett          14352 Mussey Grade Rd.
  10.  *    CIS: 70304,1423         Ramona, CA 92065
  11.  * Use this file to load the development environment
  12.  * extensions for use with the Actor programming
  13.  * language.
  14.  *     load("extend.lod");
  15.  *     load();
  16.  */
  17. #define MAXSOURCENEST 5;      /* max directory nesting */
  18. Actor[#Programmer] := "   ";  /* set this in workspace */
  19. Actor[#StampText]  := "Stamp";/* time stamp header.  Another
  20.                                * useful stamp header would be
  21.                                * "Copyright (C) 1991 XYZ, Inc."*/
  22. LoadFiles :=
  23. {
  24. /* Your path may be different. */
  25.   load(new(SourceFile),"c:\actor\general\classes\string.clx");
  26.   load(#("classes\extsource.cls"
  27.          "c:\actor\general\classes\symbol.clx"));
  28.  
  29. /* The minimum code necessary to navigate the directory
  30.  * hierarchy has now been loaded, paths are no longer needed.  */
  31.   do(#(Behavior Browser ClassDialog ClVarDialog  Function
  32.        SourceFile System ToolWind WorkEdit), {using(cl)
  33.     loadExtensions(cl);
  34.   });
  35. }!!
  36.  
  37.  
  38. [LISTING TWO]
  39.  
  40. /* EXTSOURCE.CLS - Actor development extensions
  41.  Copyright (C) 1991  Steve Hatchett. All rights reserved.
  42.  Provides access to class source code. Allows the source code for a class
  43.  to be contained in more than one file ordered hierarchically by directory
  44.  structure. There is one .cls file containing the actual class definition.  
  45.  Additional .clx files may be exist at lower levels of the hierarchy. They 
  46.  can contain methods and class initialization code. */!!
  47.  
  48. inherit(Object, #ExtSourceFiler,
  49.         #(clName      /* Name of class being handled. */
  50.           ownsClass   /* True if the .cls file for class is
  51.                          in this session's directory. */
  52.           fileNames   /* Source code file names with paths. */
  53.           ownsLast    /* True if we owned the last method
  54.                          we read. */), 2, nil)!!
  55.  
  56. now(class(ExtSourceFiler))!!
  57.  
  58. /* Return a new  ExtSourceFiler, initialized to handle source code for the 
  59.  class whose name Symbol was given. */
  60. Def openClass(self className)
  61. {
  62.   ^init(new(self),className);
  63. } !!
  64.  
  65. now(ExtSourceFiler)!!
  66.  
  67. /* Load class extension files (.clx) for the class, but don't load the class 
  68.    file (.cls). This is useful for loading extensions to the standard
  69.    Actor classes. Looks for all files in CLASSES subdirectories.  */
  70. Def loadExtensions(self | work fNames fnm)
  71. {
  72.   work := loadString(332);
  73.   if size(fileNames) > 0
  74.      cand subString(first(fileNames),0,size(work))=work
  75.     fileNames[0] := loadString(331) + getFileName(self);
  76.     if not(exists(File,fileNames[0],0))
  77.       removeFirst(fileNames);
  78.     endif;
  79.   endif;
  80.   if size(fileNames) > 0
  81.     fNames := copy(fileNames);
  82.     fnm := last(fNames);
  83.     if fnm[size(fnm)-1] == 's'
  84.       pop(fNames);       /* removes the .cls file */
  85.     endif;
  86.     ^do(reverse(fNames), {using(fnm)
  87.        load(new(SourceFile),fnm);
  88.      });
  89.   endif;
  90.   ^nil;
  91. }!!
  92.  
  93. /* Recompile the class by loading all its source code.
  94.    Looks in WORK for own source file if class is dirty.  */
  95. Def recompile(self)
  96. {
  97.   ^do(reverse(fileNames), {using(fnm)
  98.      load(new(SourceFile),fnm);
  99.    });
  100. }!!
  101.  
  102. /* Return open SourceFile with given file name (which should include path). */
  103. Def openSourceFile(self fName | sFile)
  104. {
  105.   sFile := new(SourceFile);
  106.   setName(sFile,fName);
  107.   if not(open(sFile,0))
  108.     errorBox(loadString(311), clName
  109.     + loadString(312)+fName+".");
  110.     ^nil;
  111.   endif;
  112.   ^sFile;
  113. }!!
  114.  
  115. /* If no source file exists for the class at the directory level of this actor 
  116.   session, then create an extension file in WORK, and mark class as dirty.  */
  117. Def mustHaveOwn(self | sFile)
  118. {
  119.   if size(fileNames) == 0
  120.      cor first(fileNames)[0] == '.'
  121.     add(DirtyClasses,clName);
  122.     insert(fileNames,loadString(332)
  123.                   +subString(clName,0,8)+".clx",0);
  124.     makeClassExtFile(new(SourceFile),self);
  125.   endif;
  126. }!!
  127.  
  128. /* Replace the the fSym method text with methtext, or add method text if it 
  129.   wasn't already in source file. Mode determines whether method is a class or 
  130.   object method. These changes will only be made in the source file owned by 
  131.    this actor session. Returns nil if not successful. */
  132. Def saveMethText(self methtext fSym mode | rFile wFile)
  133. {
  134.   mustHaveOwn(self);
  135.   if (rFile := openClass(SourceFile,self))
  136.     wFile := saveMethText(rFile,methtext,fSym,mode);
  137.     reName(wFile,(fileNames[0] := condDelCFile(rFile,self)));
  138.   endif;
  139.   ^rFile;
  140. }!!
  141.  
  142. /* Replace the the class initialization code, with given code. Change will 
  143.   only be made in source file owned by this actor session. Returns nil if 
  144.   not successful. */
  145. Def replaceClassInit(self text | rFile wFile)
  146. {
  147.   mustHaveOwn(self);
  148.   if (rFile := openClass(SourceFile,self))
  149.     wFile := replaceClassInit(rFile,text);
  150.     reName(wFile,(fileNames[0] := condDelCFile(rFile,self)));
  151.     close(rFile);
  152.   endif;
  153.   ^rFile;
  154. }!!
  155.  
  156. /* Return the class init code for this class as a TextCollection. */
  157. Def readClassInit(self | rFile text)
  158. {
  159. /* look through source files until some class initialization text is found.  */
  160.   ownsLast := false;
  161.   do(fileNames,{using(fnm)
  162.     if (rFile := openSourceFile(self,fnm))
  163.       text := readClassInit(rFile);
  164.       close(rFile);
  165.       if size(text) > 0
  166.         ownsLast := (fnm[0] <> '.');
  167.         ^text;
  168.       endif;
  169.     endif;
  170.   });
  171.   ^new(TextCollection,5);
  172. }!!
  173.  
  174. /* Remove the fSym method text if it is found in source file owned by this 
  175.   actor session. Mode determines whether method is a class or object method.  
  176.   Returns nil if not successful or if method was not in owned source file. */
  177. Def removeMethod(self fSym mode | rFile wFile)
  178. {
  179.   if size(fileNames) > 0
  180.      cand first(fileNames)[0] <> '.'
  181.      cand (rFile := openClass(SourceFile,self))
  182.     if wFile := replaceMethod(rFile,nil,fSym,mode)
  183.       reName(wFile,(fileNames[0] := condDelCFile(rFile,self)));
  184.     endif;
  185.     close(rFile);
  186.   endif;
  187.   ^wFile;
  188. }!!
  189.  
  190. /* Load the class by loading all its source code. Looks in CLASSES for 
  191.   all source files.  */
  192. Def load(self | work)
  193. {
  194.   work := loadString(332);
  195.   if size(fileNames) > 0
  196.      cand subString(first(fileNames),0,size(work))=work
  197.     fileNames[0] := loadString(331) + getFileName(self);
  198.     if not(exists(File,fileNames[0],0))
  199.       removeFirst(fileNames);
  200.     endif;
  201.   endif; 
  202.   ^do(reverse(fileNames), {using(fnm)
  203.      load(new(SourceFile),fnm);
  204.    });
  205. }
  206. !!
  207.  
  208. /* Return true if the last method read using loadMethText was from a source 
  209.   file at directory level of this actor session.  */
  210. Def ownsLast(self)
  211. {
  212.   ^ownsLast;
  213. }!!
  214.  
  215. /* Initialize a new ExtSourceFiler.  */
  216. Def init(self nm | metaNm)
  217. {
  218.   if class(nm) <> Symbol
  219.     nm := name(nm);
  220.   endif;
  221.   if (metaNm := isMetaName(nm))
  222.     clName := name(value(metaNm));
  223.   else
  224.     clName := nm;
  225.   endif;
  226.   getFileNames(self);
  227. }!!
  228.  
  229. /* Return true if the .cls file for the class this filer is handling exists 
  230.   at the directory level of this actor session.  */
  231. Def ownsClass(self)
  232. {
  233.   ^ownsClass;
  234. }!!
  235.  
  236. /* Return text of aMethod. Note accordingly if source code is missing. Mode 
  237.  indicates type of method, either class (BR_CMETH) or object (BR_OMETH). Looks 
  238.  through all the source files for the class.  */
  239. Def loadMethText(self aMethod mode | text rFile)
  240. {
  241. /* look through source files until the text for the given method is found.  */
  242.   ownsLast := false;
  243.   rFile := new(SourceFile);
  244.   do(fileNames,{using(fnm)
  245.     if not(rFile := openSourceFile(self,fnm))
  246.       errorBox(loadString(311), clName
  247.                +loadString(312)+fnm+".");
  248.     else
  249.       text := findMethod(rFile,aMethod,mode);
  250.       close(rFile);
  251.       if text
  252.         ownsLast := (fnm[0] <> '.');
  253.         ^leftJustify(text[0]);
  254.       endif;
  255.     endif;
  256.   });
  257.   ^aMethod + loadString(310);
  258. }!!
  259.  
  260. /* Return the class's name the way Behavior would do it.  */
  261. Def name(self)
  262. {
  263.   ^clName;
  264. }!!
  265.  
  266. /* Return the class's filename the way Behavior would do it.  */
  267. Def getFileName(self | dir)
  268. {
  269. /* return name + ext */
  270.   ^subString(clName,0,8)
  271.    + if ownsClass
  272.      ".cls" else ".clx" endif;
  273. }!!
  274.  
  275. /* Get the names of the files containing this class' source code.  */
  276. Def getFileNames(self | dir fRoot base)
  277. {
  278.   fileNames := new(OrderedCollection,MAXSOURCENEST);
  279.   dir := loadString(if clName in DirtyClasses
  280.                     332 else 331 endif);
  281.   base := subString(clName,0,8);
  282.   fRoot := dir + base;
  283.   do(MAXSOURCENEST, {using(i | fnm)
  284.  
  285. /* if the original .cls file or a .clx file is found for class, add it to list 
  286.   if it's above this session's directory.  */
  287.     if exists(File,(fnm:=fRoot+".cls"),0)
  288.       add(fileNames,fnm);
  289.       if i==0
  290.         ownsClass := true;
  291.       endif;
  292.       ^fileNames;
  293.     endif;
  294.     if exists(File,(fnm:=fRoot+".clx"),0)
  295.       add(fileNames,fnm);
  296.     endif;
  297.     
  298. /* construct the path name of the next higher level. */
  299.     if i==0
  300.       fRoot := "..\classes\"+base;
  301.     else
  302.       fRoot := "..\"+fRoot;
  303.     endif;
  304.   });
  305.   ^fileNames;
  306. }!!
  307.  
  308. /* Return the names of the files containing this class' source code  
  309.  (including own source file).  */
  310. Def fileNames(self)
  311. {
  312.   ^fileNames;
  313. }!!
  314.  
  315.  
  316. [LISTING THREE] 
  317.  
  318. /* TOOLWIND.CLX - Actor development extensions
  319.  *
  320.  * Copyright(C) 1991 Steve Hatchett.  All rights reserved.
  321.  */!!
  322. now(class(ToolWindow))!!
  323.  
  324. /* Used by the system to initialize the DirtyClasses
  325.   Set backup file.  DirtyClasses is assumed to be
  326.   empty on entry.  For each class found in the backup
  327.   file, ask the user whether to re-load the dirty
  328.   class file or use the old class file. 
  329.  
  330.   swh modified to support extended source files.
  331.   swh modified to support unique dirty class file
  332.   names between images.
  333.  */
  334. Def loadDirty(self | dName)
  335. {
  336. /* mod for unique dirty file name - base the dirty
  337.  * file name on the image name.
  338.  */
  339.   setName($DFile,subString(imageName(TheApp),0,
  340.                  indexOf(imageName(TheApp),'.',0))
  341.                  +".drt");
  342. /* end mod */
  343.  
  344.  if open($DFile, 0)
  345.   then
  346. ...
  347.   if size(DirtyClasses) > 0
  348.   then do(copy(DirtyClasses),
  349.     {using(clName)
  350.  
  351. /* mod for extended source file support - if the dirty
  352.  * class exists in the system, let it tell us its file
  353.  * name (.cls or .clx), otherwise the class was created
  354.  * since the last snapshot, so it should be a .cls file.
  355.  */
  356.       dName := loadString(332) + subString(clName,0,8)
  357.                + if not(Classes[clName])
  358.                     cor isOwnClass(Classes[clName])
  359.                   ".cls" else ".clx" endif;
  360. /* end mod */
  361.  
  362.       dName := loadString(332) + subString(clName,0,8) + ".cls";
  363. ...
  364. }!!
  365.  
  366. now(ToolWindow)!!
  367.  
  368. /* Insert/overwrite a time stamp as the first line of
  369.    the method text.
  370.  */
  371. Def stampMethText(self text fSym mode | stampHead)
  372. {
  373.   stampHead := "/*"+StampText;
  374.   
  375. /* if method doesn't already have a stamp, insert
  376.  * a line for it.
  377.  */
  378.   if left(text[0],size(stampHead),' ') <> stampHead
  379.     insert(text,"",0);
  380.   endif;
  381.   
  382. /* construct the time stamp. */
  383.   text[0] := stampHead+" "+timeStamp(System)+" "
  384.              +programmer(System)+" "+name(selClass)
  385.              +if mode == BR_CMETH 
  386.                 "(Class)" else "" endif
  387.              +":"+fSym+" */";
  388. }!!
  389.  
  390. /* Save the new text for current method into the source
  391.   file. The first argument, text, is the method text.  The
  392.   second, fSym, is the symbol with the name of the method,
  393.   e.g. #print.  The new or revised method text ends up in a
  394.   class source file in WORK.  Also, write the text to the
  395.   change log.
  396.   
  397.   swh modified to support extended source files
  398.   swh modified to support automatic time stamping
  399.  */
  400. Def saveMethText(self, text, fSym | textEnd, nowCl, rFile, wFile)
  401. {...
  402.     changeLog(ew, "now(" + nowCl + ")" + Chunk +
  403.       subText(text, 0, 0, textEnd, size(text[textEnd])));
  404.       
  405. /* mod for automatic time stamps
  406.  * place time stamp in method text.
  407.  */
  408.     if text
  409.       stampMethText(self,text,fSym,mode);
  410.     endif;
  411. /* end mod */
  412.  
  413. /* mod to support extended source files */
  414.     saveMethText(openClass(ExtSourceFiler,selClass),
  415.                  text, fSym, mode);
  416. /* end mod */
  417.  
  418.     makeDirty(self);
  419.   endif;
  420.   ^fSym;
  421. }!!
  422.  
  423. /* ToolWindow class initialization 
  424.    Rewritten to override ToolWindow.cls class
  425.    initialization to support unique dirty file
  426.    names between images - base the dirty file
  427.    name on the image name.
  428.  */
  429. $DFile := setName(new(TextFile),
  430.                   subString(imageName(TheApp),0,
  431.                      indexOf(imageName(TheApp),'.',0))
  432.                   +".drt");
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.